#include <wfcClient.h>
#include <wfcSession.h>
#include <wxyutils.h>
#include <wxyDrawing.h>

#include <ProToolkitErrors.h>
#include "main.h"
#include <ProModelitem.h>
#include <ProSelection.h>
#include <ProSelbuffer.h>
#include <ProWindows.h>
#include <ProConst.h>
#include <ProSolid.h>
#include <ProFeatType.h>
#include <ProArray.h>
#include <vector>
#include <ProVariantFeat.h>
#define CHECK_STATUS(status)       \
    if (status != PRO_TK_NO_ERROR) \
    {                              \
        LOG(LOG_ERROR) << status;  \
        return wfcTK_NO_ERROR;     \
    }

double _myand()
{
    return (double)(rand() % 1001) * 0.001f;
}

wfcStatus RepaintPart(ProModelitem modelitem)
{
    ProError status;
    ProSurfaceAppearanceProps proprop_orig;
    status = ProSurfaceAppearancepropsGet(&modelitem, &proprop_orig);
    /*
    typedef struct pro_surf_appearance_props
    {
    double ambient;
    double diffuse;
    double highlite;
    double shininess;
    double transparency;
    ProVector color_rgb;
    ProVector highlight_color;
    double reflection;
    ProPath name;
    ProPath label;
    ProPath description;
    ProPath keywords;
    } ProSurfaceAppearanceProps;
    */
    ProSurfaceAppearanceProps proprop = {0.8, 0.8, 0.7, 0.6, 0.0, {_myand(), _myand(), _myand()}, {0, 0, 1}, proprop_orig.reflection, *proprop_orig.name, *proprop_orig.label, *proprop_orig.description, *proprop_orig.keywords};

    status = ProSurfaceAppearancepropsSet(&modelitem, &proprop);
    return wfcTK_NO_ERROR;
}
void TransparencyPart(ProModelitem modelitem)
{
    ProError status;
    ProSurfaceAppearanceProps proprop_orig;
    status = ProSurfaceAppearancepropsGet(&modelitem, &proprop_orig);
    ProSurfaceAppearanceProps proprop = {0.8, 0.8, 0.7, 0.6, 1.0, {_myand(), _myand(), _myand()}, {0, 0, 1}, proprop_orig.reflection, *proprop_orig.name, *proprop_orig.label, *proprop_orig.description, *proprop_orig.keywords};
    status = ProSurfaceAppearancepropsSet(&modelitem, &proprop);
}
ProError AsmCompFilter(ProFeature *feature, ProAppData app_data)
{
    ProError status;
    ProFeattype ftype;
    status = ProFeatureTypeGet(feature, &ftype);
    if (ftype == PRO_FEAT_COMPONENT)
        return PRO_TK_NO_ERROR;
    return PRO_TK_CONTINUE;
}
ProError AsmVisitAcFn(ProFeature *p_object, ProError status, vector<ProFeature> *app_data)
{
    ProBoolean isVisible;
    ProFeatStatus p_status;
    ProMdl mdl;
    ProModelitem modelitem;

    status = ProFeatureStatusGet(p_object, &p_status);
    status = ProFeatureVisibilityGet(p_object, &isVisible);
    if (isVisible == PRO_B_TRUE && p_status != PRO_FEAT_SUPPRESSED)
    {
        status = ProAsmcompMdlGet((ProAsmcomp *)(p_object), (ProMdl *)&mdl);
        status = ProMdlToModelitem(mdl, &modelitem);
        if (modelitem.type == PRO_ASSEMBLY)
        {
            status = ProSolidFeatVisit((ProSolid)mdl, (ProFeatureVisitAction)AsmVisitAcFn, AsmCompFilter, app_data);
        }
        else
        {
            RepaintPart(modelitem);
        }
    }
    return PRO_TK_NO_ERROR;
}

wfcStatus ColorPart()
{
    ProError status;
    ProSelection *p_sel;
    int n_sel = 0;
    status = ProSelbufferSelectionsGet(&p_sel);
    // status = ProSelect((char *)"part", 1, NULL, NULL, NULL, NULL, &p_sel, &n_sel);
    CHECK_STATUS(status)
    status = ProArraySizeGet((ProArray)p_sel, &n_sel);
    if (n_sel > 0)
    {
        for (int i = 0; i < n_sel; i++)
        {
            ProModelitem modelitem;
            status = ProSelectionModelitemGet(p_sel[i], &modelitem);
            CHECK_STATUS(status)
            RepaintPart(modelitem);
        }
    }
    ProSelectionarrayFree(p_sel);
    ProWindowRefresh(PRO_VALUE_UNUSED);
    return wfcTK_NO_ERROR;
}
wfcStatus TransPart()
{
    ProError status;
    ProSelection *p_sel;
    int n_sel = 0;
    status = ProSelbufferSelectionsGet(&p_sel);
    // status = ProSelect((char *)"part", 1, NULL, NULL, NULL, NULL, &p_sel, &n_sel);
    CHECK_STATUS(status)
    status = ProArraySizeGet((ProArray)p_sel, &n_sel);
    if (n_sel > 0)
    {
        for (int i = 0; i < n_sel; i++)
        {
            ProModelitem modelitem;
            status = ProSelectionModelitemGet(p_sel[i], &modelitem);
            CHECK_STATUS(status)
            TransparencyPart(modelitem);
        }
    }
    ProSelectionarrayFree(p_sel);
    ProWindowRefresh(PRO_VALUE_UNUSED);
    return wfcTK_NO_ERROR;
}

wfcStatus RandColor()
{
    ProError status;
    ProMdl mdl;
    vector<ProFeature> feat_list;
    status = ProMdlCurrentGet(&mdl);
    srand((unsigned int)time(0));
    status = ProSolidFeatVisit((ProSolid)mdl, (ProFeatureVisitAction)AsmVisitAcFn, AsmCompFilter, (vector<ProFeature> *)&feat_list);
    CHECK_STATUS(status)
    status = ProWindowRepaint(PRO_VALUE_UNUSED);
    return wfcTK_NO_ERROR;
}